Note: This tutorial assumes that you have completed the previous tutorials: Rviz Interactions. |
Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
Web App Interactions
Description: Defining interactions for web apps.Keywords: rocon interactions
Tutorial Level: BEGINNER
Next Tutorial: Android Interactions
Contents
Overview
This tutorial will guide you through the process of running and launching ros web apps. This has a really strong advantage in that it provides a systematic way of getting parameters, remappings and rosbridge info to the web app itself.
Interactions
Yaml
The interaction yaml is relatively straightforward with the only new feature the addition of the ROSBRIDGE_ADRESS , ROSBRIDGE_PORT and WEBSERVER_ADDRESS symbols. The interaction node will substitute these with the real values of the rosbridge uri and webapp hosting server upon loading them. We'll also make use of the existing web app being served from the rocon tools github pages.
Save this as foo.interactions in foo.
1 - name: web_app(http://__WEBSERVER_ADDRESS__/rocon_tools/js/current/listener.html)
2 role: 'Beginners'
3 compatibility: rocon:/*/*/hydro|indigo
4 display_name: Listener
5 description: Simple listener using rosjs in a web app.
6 icon:
7 resource_name: rocon_bubble_icons/rocon.png
8 parameters:
9 rosbridge_address: __ROSBRIDGE_ADDRESS__
10 rosbridge_port: __ROSBRIDGE_PORT__
11 remappings:
12 - remap_from: /chatter
13 remap_to: /babbler
Note that your web app doesn't have to be served in a location connected to your ros master network. However your remocon (qt or android) must be in a position to connect to the final rosbridge uri socket.
Launcher
The launcher is as before with the addition of both the rosbridge server, rosbridge params and a talker for the listener web app to interact with.
Save this as foo.launch in foo.
1 <launch>
2 <arg name="rosbridge_address" default="localhost"/>
3 <arg name="rosbridge_port" default="8080"/>
4 <arg name="webserver_address" default="robotics-in-concert.github.io"/>
5
6 <param name="name" value="Rocon Web App Interactions"/>
7 <param name="description" value="A tutorial environment for web app interactions (using rosbridge)) and remocons."/>
8 <param name="icon" value="rocon_icons/cybernetic_pirate.png"/>
9 <node pkg="rocon_master_info" type="master.py" name="master"/>
10
11 <node pkg="rocon_interactions" type="interactions_manager.py" name="interactions">
12 <rosparam param="interactions">[foo/foo]</rosparam>
13 <param name="rosbridge_address" value="$(arg rosbridge_address)"/>
14 <param name="rosbridge_port" value="$(arg rosbridge_port)"/>
15 <param name="webserver_address" value="$(arg webserver_address)"/>
16 </node>
17
18 <include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch" >
19 <arg name="address" value="$(arg rosbridge_address)"/>
20 <arg name="port" value="$(arg rosbridge_port)"/>
21 </include>
22
23 <node pkg="roscpp_tutorials" type="talker" name="talker">
24 <remap from="chatter" to="babbler"/>
25 </node>
26 </launch>
Web App
The web app being served by github pages looks like:
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8" />
5
6 <script type="text/javascript" src="http://cdn.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script>
7 <script type="text/javascript" src="http://cdn.robotwebtools.org/roslibjs/current/roslib.min.js"></script>
8 <script type="text/javascript" src="http://robotics-in-concert.github.io/rocon_tools/js/hydro/interactions.js"></script>
9 <script type="text/javascript" type="text/javascript">
10
11 console.log("Display Name : " + rocon_interactions.display_name)
12 console.log("Rosbridge URI: " + rocon_interactions.rosbridge_uri)
13 console.log("Parameters : " + JSON.stringify(rocon_interactions.parameters))
14 console.log("Remappings : " + JSON.stringify(rocon_interactions.remappings))
15
16 // Connecting to ROS
17 // -----------------
18 var ros = new ROSLIB.Ros({
19 url : rocon_interactions.rosbridge_uri
20 //url : 'ws://localhost:8080'
21 });
22
23 // Subscribing to a Topic
24 // ----------------------
25 var topic_name = '/chatter'
26 if (topic_name in rocon_interactions.remappings)
27 topic_name = rocon_interactions.remappings[topic_name]
28 var listener = new ROSLIB.Topic({
29 ros : ros,
30 name : topic_name,
31 messageType : 'std_msgs/String'
32 });
33
34 listener.subscribe(function(message) {
35 console.log('Received message on ' + listener.name + ': ' + message.data);
36 listener.unsubscribe();
37 });
38 </script>
39 </head>
40
41 <body>
42 <h1>Rocon Interactions Listener Demo</h1>
43 <p>Check your Web Console for output (hit F12 in google chrome).</p>
44 </body>
45 </html>
Pretty simple?
Interacting
Make sure you have google chrome supported (we haven't extended support to other browsers yet).
# Dependencies > sudo apt-get install ros-indigo-rosbridge-suite ros-indigo-rosauth ros-indigo-roscpp-tutorials # In the first shell > roslaunch foo foo.launch --screen # In a second shell > rocon_remocon
Add your ros master, connect, choose the 'Beginners' role and finally fire up the 'Listener'. If you're in google, hit F12 and select the dev console, you will see output from the websocket appearing there.
Appendix
Workflow Sketch
A rough sketch of the workflow in initiating a web app via an interaction:
Interactions Javascript Module
When the web app is launched by a remocon, it loads interactions data (display name, parameters and remappings) into the query string so that you might get a url looking like the bewildering obtuse:
http://robotics-in-concert.github.io/rocon_tools/js/current/listener.html?interaction_data=%7B%22remappings%22%3A+%7B%22%2Fchatter%22%3A+%22%2Fbabbler%22%7D%2C+%22display_name%22%3A+%22Listener%22%2C+%22parameters%22%3A+%7B%22rosbridge_address%22%3A+%22localhost%22%2C+%22rosbridge_port%22%3A+8080%7D%7D
If that seems like alot to parse, yes it is! Which is exactly why we've written some js magic to help you extract those variables. Simply include the interactions.js script served by github pages and access the rocon_interactions singleton object. In particular, the following lines:
1 <script type="text/javascript" src="http://robotics-in-concert.github.io/rocon_tools/js/hydro/interactions.js"></script>
2 <script type="text/javascript" type="text/javascript">
3 console.log("Display Name : " + rocon_interactions.display_name)
4 console.log("Rosbridge URI: " + rocon_interactions.rosbridge_uri)
5 console.log("Parameters : " + JSON.stringify(rocon_interactions.parameters))
6 console.log("Remappings : " + JSON.stringify(rocon_interactions.remappings))